
#import "MyHTTPConnection.h"
#import "HTTPMessage.h"
#import "HTTPDataResponse.h"
#import "DDNumber.h"
#import "HTTPLogging.h"

#import "MultipartFormDataParser.h"
#import "MultipartMessageHeaderField.h"
#import "HTTPDynamicFileResponse.h"
#import "HTTPFileResponse.h"

#import "NSString+URL.h"
#import "AppConfig.h"
#import "AppContext.h"
#import "StringUtil.h"

// Log levels : off, error, warn, info, verbose
// Other flags: trace
static const int httpLogLevel = HTTP_LOG_LEVEL_VERBOSE; // | HTTP_LOG_FLAG_TRACE;


/**
 * All we have to do is override appropriate methods in HTTPConnection.
 **/

@implementation MyHTTPConnection

- (BOOL)isSecureServer
{
    
    HTTPLogTrace();
    // Create an HTTPS server (all connections will be secured via SSL/TLS)
    return YES;
}

/**
 * This method is expected to returns an array appropriate for use in kCFStreamSSLCertificates SSL Settings.
 * It should be an array of SecCertificateRefs except for the first element in the array, which is a SecIdentityRef.
 **/
- (NSArray *)sslIdentityAndCertificates
{
    HTTPLogTrace();
    
    SecIdentityRef identityRef = NULL;
    SecCertificateRef certificateRef = NULL;
    SecTrustRef trustRef = NULL;
    
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"2_ios127.whwangdoudou.cn" ofType:@"p12"];
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
    CFStringRef password = CFSTR("");
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };
    CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    
    OSStatus securityError = errSecSuccess;
    securityError =  SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
    if (securityError == 0) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemIdentity);
        identityRef = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);
        trustRef = (SecTrustRef)tempTrust;
    } else {
        NSLog(@"Failed with error code %d",(int)securityError);
        return nil;
    }
    
    SecIdentityCopyCertificate(identityRef, &certificateRef);
    NSArray *result = [[NSArray alloc] initWithObjects:(id)CFBridgingRelease(identityRef), (id)CFBridgingRelease(certificateRef), nil];
    
    return result;
}



- (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path
{
	HTTPLogTrace();
	
	// Add support for POST
	
	if ([method isEqualToString:@"POST"])
	{
		if ([path isEqualToString:@"/upload.html"])
		{
			return YES;
		}
	}
	
	return [super supportsMethod:method atPath:path];
}

- (BOOL)expectsRequestBodyFromMethod:(NSString *)method atPath:(NSString *)path
{
	HTTPLogTrace();
	
	// Inform HTTP server that we expect a body to accompany a POST request
	
	if([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"]) {
        // here we need to make sure, boundary is set in header
        NSString* contentType = [request headerField:@"Content-Type"];
        NSUInteger paramsSeparator = [contentType rangeOfString:@";"].location;
        if( NSNotFound == paramsSeparator ) {
            return NO;
        }
        if( paramsSeparator >= contentType.length - 1 ) {
            return NO;
        }
        NSString* type = [contentType substringToIndex:paramsSeparator];
        if( ![type isEqualToString:@"multipart/form-data"] ) {
            // we expect multipart/form-data content type
            return NO;
        }

		// enumerate all params in content-type, and find boundary there
        NSArray* params = [[contentType substringFromIndex:paramsSeparator + 1] componentsSeparatedByString:@";"];
        for( NSString* param in params ) {
            paramsSeparator = [param rangeOfString:@"="].location;
            if( (NSNotFound == paramsSeparator) || paramsSeparator >= param.length - 1 ) {
                continue;
            }
            NSString* paramName = [param substringWithRange:NSMakeRange(1, paramsSeparator-1)];
            NSString* paramValue = [param substringFromIndex:paramsSeparator+1];
            
            if( [paramName isEqualToString: @"boundary"] ) {
                // let's separate the boundary from content-type, to make it more handy to handle
                [request setHeaderField:@"boundary" value:paramValue];
            }
        }
        // check if boundary specified
        if( nil == [request headerField:@"boundary"] )  {
            return NO;
        }
        return YES;
    }
	return [super expectsRequestBodyFromMethod:method atPath:path];
}

//字典转json字符串
-(NSString *)convertToJsonData:(NSDictionary *)dict

{
    
    NSError *error;
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
    
    NSString *jsonString;
    
    if (!jsonData) {
        
        NSLog(@"%@",error);
        
    }else{
        
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
        
    }
    
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    
    NSRange range = {0,jsonString.length};
    
    //去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    
    NSRange range2 = {0,mutStr.length};
    
    //去掉字符串中的换行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    
    return mutStr;
    
}

//jsonStr转字典
-(NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString
{
    if (jsonString == nil) {
        return nil;
    }
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *err;
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
    if(err)
    {
        NSLog(@"json解析失败：%@",err);
        return nil;
    }
    return dic;
}


- (NSObject<HTTPResponse> *)httpResponseForMethod:(NSString *)method URI:(NSString *)path
{
	HTTPLogTrace();
    
    if ([path hasPrefix:@"/getClient_no"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[path URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSString *idfa = [AppConfig getAppIDFA];
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"no"] = idfa;
        responsDic[@"client_no"] = [AppContext sharedContext].clientId;
        responsDic[@"state"] = @"1";
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    //获取当前用户信息
    if ([path hasPrefix:@"/getLoadUserInfo"])
    {
        
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[path URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSArray *array3 = [[path URLDecodedString] componentsSeparatedByString:@"udid="];
        NSArray *array4 = [array3.lastObject componentsSeparatedByString:@"&"];
        NSString *udid = array4.firstObject;
        [AppContext sharedContext].udid = udid;
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        
        NSMutableDictionary *param = [NSMutableDictionary dictionary];
        param[@"udid"]=[AppContext sharedContext].udid;
        [[ApiClient sharedApi] yiqishike_userp:param cb:^(NSDictionary *data, NSError *connectionError) {
            
            if ([data[@"code"] isEqualToString:@"0"]) {
                NSDictionary *result = data[@"result"];
                [AppContext sharedContext].uid = result[@"id"];
                responsDic[@"k"] = result[@"kid"];
                responsDic[@"i"] = @"1";
                responsDic[@"u"] = @"0";
                responsDic[@"e"] = @"0";
                responsDic[@"client_no"] = result[@"client_no"];
                responsDic[@"state"] = @"1";
            }else {
                responsDic[@"k"] = @"";
                responsDic[@"i"] = @"";
                responsDic[@"u"] = @"";
                responsDic[@"e"] = @"";
                responsDic[@"client_no"] = @"";
                responsDic[@"state"] = @"0";
            }
        }];
        //        [[ApiClient sharedApi] yiqishike_phone:@{} cb:^(NSDictionary *data, NSError *connectionError) {
        //           NSLog(@"phone_data:===%@ error===%@",data,connectionError.localizedDescription);
        //        }];
        
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        NSLog(@"responsDic===%@ \n responsStr===%@",responsDic,responsStr);
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/getOnlineStatus"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[path URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"state"] = [AppContext sharedContext].isStatus;
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/getBreakStatus"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [path componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"state"] = @"1";
        responsDic[@"isBreak"] = [AppConfig isJailBreak];
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/pasteAction"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[path URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        
        NSArray *array3 = [[path URLDecodedString] componentsSeparatedByString:@"taskid="];
        NSArray *array4 = [array3.lastObject componentsSeparatedByString:@"&"];
        NSString *taskid = array4.firstObject;
        
        NSArray *array5 = [[path URLDecodedString] componentsSeparatedByString:@"key="];
        NSArray *array6 = [array5.lastObject componentsSeparatedByString:@"&"];
        NSString *key = array6.firstObject;
        
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        if ([taskid isEqualToString:@"0"]) {
            [StringUtil copyTxt:key];
        }else {
            [StringUtil copyTxt:key];
            NSMutableDictionary *param = [NSMutableDictionary dictionary];
            param[@"udid"]=[AppContext sharedContext].udid;
            param[@"uid"]=[AppContext sharedContext].uid;
            param[@"taskid"]=taskid;
            param[@"keyword"]=key;
            [[ApiClient sharedApi] yiqishike_logd:param cb:^(NSDictionary *data, NSError *connectionError) {
                if ([data[@"code"] isEqualToString:@"0"]) {
                    responsDic[@"state"] = @"1";
                }else {
                    responsDic[@"state"] = @"0";
                }
            }];
        }
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/getReInstallStatus"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[[path URLDecodedString] URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSArray *array3 = [[path URLDecodedString] componentsSeparatedByString:@"bundleid="];
        NSArray *array4 = [array3.lastObject componentsSeparatedByString:@"&"];
        NSString *bundleid = array4.firstObject;
        BOOL isInstall = [AppConfig  checkAppIsInstalled:bundleid];
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"state"] = isInstall?@"1":@"0";
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/openApp"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [[path URLDecodedString] componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSArray *array3 = [[path URLDecodedString] componentsSeparatedByString:@"taskid="];
        NSArray *array4 = [array3.lastObject componentsSeparatedByString:@"&"];
        NSString *taskid = array4.firstObject;
        
        NSArray *array5 = [[path URLDecodedString] componentsSeparatedByString:@"bundleid="];
        NSArray *array6 = [array5.lastObject componentsSeparatedByString:@"&"];
        NSString *bundleid = array6.firstObject;
        
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        
        BOOL isOpen = [AppConfig  openAppWithBundleID:bundleid];
        if (isOpen) {
            NSMutableDictionary *param = [NSMutableDictionary dictionary];
            param[@"udid"]=[AppContext sharedContext].udid;
            param[@"uid"]=[AppContext sharedContext].uid;
            param[@"taskid"]=taskid;
            [[ApiClient sharedApi] yiqishike_send_active:param cb:^(NSDictionary *data, NSError *connectionError) {
                if ([data[@"code"] isEqualToString:@"0"]) {
                    responsDic[@"state"] = @"1";
                    responsDic[@"isOpen"] = @"1";
                }else {
                    responsDic[@"state"] = @"0";
                    responsDic[@"isOpen"] = @"0";
                }
            }];
        }else {
            responsDic[@"state"] = @"0";
            responsDic[@"isOpen"] = @"0";
        }
        
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/getInstallStatus"])
    {
        HTTPLogVerbose(@"%@[%p]: postContentLength: %qu", THIS_FILE, self, requestContentLength);
        NSArray *array1 = [path componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        
        NSArray *array3 = [[path URLDecodedString] componentsSeparatedByString:@"bundleid="];
        NSArray *array4 = [array3.lastObject componentsSeparatedByString:@"&"];
        NSString *bundleid = array4.firstObject;
        
        BOOL isInstall = [AppConfig checkAppIsInstalled:bundleid];
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"state"] = isInstall?@"1":@"0";
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
    if ([path hasPrefix:@"/safariHttpSave"]) {
        NSArray *array1 = [path componentsSeparatedByString:@"callback="];
        NSArray *array2 = [array1.lastObject componentsSeparatedByString:@"&"];
        NSString *meth = array2.firstObject;
        NSArray *array = [[path URLDecodedString] componentsSeparatedByString:@"shouquan="];
        [AppContext sharedContext].accredit = array.lastObject;
        NSMutableDictionary *responsDic = [NSMutableDictionary dictionary];
        responsDic[@"state"] = @"1";
        NSString *jsonStr = [self convertToJsonData:responsDic];
        NSString *responsStr = [NSString stringWithFormat:@"%@(%@)",meth,jsonStr];
        NSData *responseData = [responsStr dataUsingEncoding:NSUTF8StringEncoding];
        return [[HTTPDataResponse alloc] initWithData:responseData];
    }
    
	
	if ([method isEqualToString:@"POST"] && [path isEqualToString:@"/upload.html"])
	{

		// this method will generate response with links to uploaded file
		NSMutableString* filesStr = [[NSMutableString alloc] init];

		for( NSString* filePath in uploadedFiles ) {
			//generate links
			[filesStr appendFormat:@"<a href=\"%@\"> %@ </a><br/>",filePath, [filePath lastPathComponent]];
		}
		NSString* templatePath = [[config documentRoot] stringByAppendingPathComponent:@"upload.html"];
		NSDictionary* replacementDict = [NSDictionary dictionaryWithObject:filesStr forKey:@"MyFiles"];
		// use dynamic file response to apply our links to response template
		return [[HTTPDynamicFileResponse alloc] initWithFilePath:templatePath forConnection:self separator:@"%" replacementDictionary:replacementDict];
	}
	if( [method isEqualToString:@"GET"] && [path hasPrefix:@"/upload/"] ) {
		// let download the uploaded files
		return [[HTTPFileResponse alloc] initWithFilePath: [[config documentRoot] stringByAppendingString:path] forConnection:self];
	}
	
	return [super httpResponseForMethod:method URI:path];
}

- (void)prepareForBodyWithSize:(UInt64)contentLength
{
	HTTPLogTrace();
	
	// set up mime parser
    NSString* boundary = [request headerField:@"boundary"];
    parser = [[MultipartFormDataParser alloc] initWithBoundary:boundary formEncoding:NSUTF8StringEncoding];
    parser.delegate = self;

	uploadedFiles = [[NSMutableArray alloc] init];
}

- (void)processBodyData:(NSData *)postDataChunk
{
	HTTPLogTrace();
    // append data to the parser. It will invoke callbacks to let us handle
    // parsed data.
    [parser appendData:postDataChunk];
}


//-----------------------------------------------------------------
#pragma mark multipart form data parser delegate


- (void) processStartOfPartWithHeader:(MultipartMessageHeader*) header {
	// in this sample, we are not interested in parts, other then file parts.
	// check content disposition to find out filename

    MultipartMessageHeaderField* disposition = [header.fields objectForKey:@"Content-Disposition"];
	NSString* filename = [[disposition.params objectForKey:@"filename"] lastPathComponent];

    if ( (nil == filename) || [filename isEqualToString: @""] ) {
        // it's either not a file part, or
		// an empty form sent. we won't handle it.
		return;
	}    
//    NSString* uploadDirPath = [[config documentRoot] stringByAppendingPathComponent:@"upload"];
    NSString* uploadDirPath = kMusicPath;

	BOOL isDir = YES;
	if (![[NSFileManager defaultManager]fileExistsAtPath:uploadDirPath isDirectory:&isDir ]) {
		[[NSFileManager defaultManager]createDirectoryAtPath:uploadDirPath withIntermediateDirectories:YES attributes:nil error:nil];
	}
	
    NSString* filePath = [uploadDirPath stringByAppendingPathComponent: filename];
    if( [[NSFileManager defaultManager] fileExistsAtPath:filePath] ) {
        storeFile = nil;
    }
    else {
		HTTPLogVerbose(@"Saving file to %@", filePath);
		if(![[NSFileManager defaultManager] createDirectoryAtPath:uploadDirPath withIntermediateDirectories:true attributes:nil error:nil]) {
			HTTPLogError(@"Could not create directory at path: %@", filePath);
		}
		if(![[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]) {
			HTTPLogError(@"Could not create file at path: %@", filePath);
		}
		storeFile = [NSFileHandle fileHandleForWritingAtPath:filePath];
		[uploadedFiles addObject: [NSString stringWithFormat:@"/upload/%@", filename]];
    }
}

//获取上行参数
- (NSDictionary *)getRequestParam:(NSData *)rawData
{
    if (!rawData) return nil;
    
    NSString *raw = [[NSString alloc] initWithData:rawData encoding:NSUTF8StringEncoding];
    NSMutableDictionary *paramDic = [NSMutableDictionary dictionary];
    NSArray *array = [raw componentsSeparatedByString:@"&"];
    for (NSString *string in array) {
        NSArray *arr = [string componentsSeparatedByString:@"="];
        NSString *value = [arr.lastObject stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [paramDic setValue:value forKey:arr.firstObject];
    }
    return [paramDic copy];
}

- (NSData *)preprocessResponse:(HTTPMessage *)response {
    
    NSString *now = [self dateAsString:[NSDate date]];
    [response setHeaderField:@"Date" value:now];
    
    // Add server capability headers
    [response setHeaderField:@"Accept-Ranges" value:@"bytes"];
    //允许跨域访问
    [response setHeaderField:@"Access-Control-Allow-Origin" value:@"*"];
    [response setHeaderField:@"Access-Control-Allow-Headers" value:@"X-Requested-With"];
    [response setHeaderField:@"Access-Control-Allow-Methods" value:@"PUT,POST,GET,DELETE,OPTIONS"];
    
    // Add optional response headers
    if ([httpResponse respondsToSelector:@selector(httpHeaders)])
    {
        NSDictionary *responseHeaders = [httpResponse httpHeaders];
        
        NSEnumerator *keyEnumerator = [responseHeaders keyEnumerator];
        NSString *key;
        
        while ((key = [keyEnumerator nextObject]))
        {
            NSString *value = [responseHeaders objectForKey:key];
            
            [response setHeaderField:key value:value];
        }
    }
    
    return [response messageData];
}

- (NSData *)preprocessErrorResponse:(HTTPMessage *)response {
    
    // Add standard headers
    NSString *now = [self dateAsString:[NSDate date]];
    [response setHeaderField:@"Date" value:now];
    
    // Add server capability headers
    [response setHeaderField:@"Accept-Ranges" value:@"bytes"];
    //允许跨域访问
    [response setHeaderField:@"Access-Control-Allow-Origin" value:@"*"];
    [response setHeaderField:@"Access-Control-Allow-Headers" value:@"X-Requested-With"];
    [response setHeaderField:@"Access-Control-Allow-Methods" value:@"PUT,POST,GET,DELETE,OPTIONS"];
    
    // Add optional response headers
    if ([httpResponse respondsToSelector:@selector(httpHeaders)])
    {
        NSDictionary *responseHeaders = [httpResponse httpHeaders];
        
        NSEnumerator *keyEnumerator = [responseHeaders keyEnumerator];
        NSString *key;
        
        while((key = [keyEnumerator nextObject]))
        {
            NSString *value = [responseHeaders objectForKey:key];
            
            [response setHeaderField:key value:value];
        }
    }
    
    return [response messageData];
}

- (NSString *)dateAsString:(NSDate *)date
{
    
    static NSDateFormatter *df;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        // Example: Sun, 06 Nov 1994 08:49:37 GMT
        
        df = [[NSDateFormatter alloc] init];
        [df setFormatterBehavior:NSDateFormatterBehavior10_4];
        [df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
        [df setDateFormat:@"EEE, dd MMM y HH:mm:ss 'GMT'"];
        [df setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
        
        // For some reason, using zzz in the format string produces GMT+00:00
    });
    
    return [df stringFromDate:date];
}


- (void) processContent:(NSData*) data WithHeader:(MultipartMessageHeader*) header 
{
	// here we just write the output from parser to the file.
	if( storeFile ) {
		[storeFile writeData:data];
	}
}

- (void) processEndOfPartWithHeader:(MultipartMessageHeader*) header
{
	// as the file part is over, we close the file.
	[storeFile closeFile];
	storeFile = nil;
}

- (void) processPreambleData:(NSData*) data 
{
    // if we are interested in preamble data, we could process it here.

}

- (void) processEpilogueData:(NSData*) data 
{
    // if we are interested in epilogue data, we could process it here.
    [[NSNotificationCenter defaultCenter] postNotificationName:@"processEpilogueData" object:nil];

}

@end
